<template>
  <div class="form">
    <label class="form-title">{{ form.title }}</label>
    <el-form
      ref="refForm"
      :model="state.formData"
      :size="form.size"
      :label-position="form.labelPosition"
      :label-width="`${form.labelWidth}px`"
    >
      <el-row>
        <el-col v-for="(c, idx) in comps" :key="idx" :style="colStyle" :span="c.propsData.col" class="comp">
          <component
            v-if="c.permission[taskKey] && c.permission[taskKey].visible"
            :is="getCompWin(c.config.compTag)"
            :data="getData(c)"
            :form="form"
            :mode="mode"
            @value-change="onChange"
          />
        </el-col>
      </el-row>
    </el-form>
    <div class="footer">
      <el-button style="width: 100px" @click="onClose">关闭</el-button>
      <template v-if="mode == 'apply'">
        <el-button type="primary" style="width: 100px" :loading="props.loading" @click="onSubmit">提交</el-button>
      </template>
      <template v-if="mode == 'approve'">
        <el-button type="primary" style="width: 100px" :loading="props.loading" @click="onApprove({ pass: true })">
          同意
        </el-button>
        <el-button
          v-if="btn && btn.reject.allow"
          type="danger"
          style="min-width: 100px"
          :loading="props.loading"
          @click="onApprove({ pass: false })"
        >
          {{ btn.reject.name }}
        </el-button>
        <el-button
          v-if="btn && btn.back.allow"
          type="warning"
          style="min-width: 100px"
          :loading="props.loading"
          @click="onApprove({ back: true })"
        >
          {{ btn.back.name }}
        </el-button>
        <el-button
          v-if="btn && btn.backToFirst.allow"
          type="warning"
          style="min-width: 100px"
          :loading="props.loading"
          @click="onApprove({ backToFirst: true })"
        >
          {{ btn.backToFirst.name }}
        </el-button>
        <el-button
          v-if="btn && btn.forward.allow"
          type="warning"
          style="min-width: 100px"
          :loading="props.loading"
          @click="onApprove({ forward: true })"
        >
          {{ btn.forward.name }}
        </el-button>
      </template>
    </div>
  </div>
</template>

<script setup lang="ts">
import { computed, reactive, ref } from 'vue'
import { ElForm } from 'element-plus'
import type { DesignItemStruct } from '@/typings'
import { useComponent } from '../design/render/hooks'

const props = withDefaults(
  defineProps<{
    form: Record<string, any>
    comps: DesignItemStruct[]
    dataValue?: any
    loading?: boolean
    taskKey?: string
    apply?: boolean
    view?: boolean
    approve?: boolean
  }>(),
  { apply: false, view: false, taskKey: '' }
)
const emits = defineEmits(['submit', 'close', 'approve'])

const refForm = ref()
const state = reactive({ formData: {} as any })

const colStyle = computed(() => {
  const margin = `margin-top: ${props.form.rowSpacing / 2}px; margin-bottom: ${props.form.rowSpacing / 2}px;`
  return `${margin}`
})

const { getCompWin } = useComponent()

const mode = computed(() => {
  if (props.approve) {
    return 'approve'
  } else if (props.apply) {
    return 'apply'
  } else if (props.view) {
    return 'view'
  } else {
    return 'view'
  }
})

const btn = computed(() => props.form.button[props.taskKey])

const getData = (comp: DesignItemStruct) => {
  let propsData: any
  if (props.taskKey) {
    propsData = Object.assign({}, comp.propsData, {
      readonly: !comp.permission[props.taskKey].modify,
      remove: comp.permission[props.taskKey].remove
    })
  } else if (props.view) {
    propsData = Object.assign({}, comp.propsData, {
      readonly: true,
      remove: false
    })
  } else {
    propsData = comp.propsData
  }
  if (props.dataValue) {
    //赋值内容
    propsData.defaultVal = props.dataValue[propsData.field]
  }
  return propsData
}

const onChange = (obj: any) => {
  state.formData[obj.name] = obj.value
}
const onSubmit = () => {
  refForm.value.validate((valid: boolean) => {
    if (valid) {
      emits('submit', {
        title: props.form.title,
        formJson: JSON.stringify(props),
        formValue: JSON.stringify(state.formData)
      })
    }
  })
}
const onApprove = (params: any) => {
  refForm.value.validate((valid: boolean) => {
    if (valid) {
      const flowParams = { ...params }
      for (let key in state.formData) {
        if (key.startsWith('approve')) {
          flowParams[key] = state.formData[key]
        }
      }
      emits('approve', {
        formValue: JSON.stringify(state.formData),
        flowParams
      })
    }
  })
}
const onClose = () => {
  emits('close')
}
</script>

<style lang="scss" scoped>
.form-title {
  margin-bottom: 20px;
  padding-bottom: 10px;
  display: block;
  text-align: center;
  font-weight: bold;
  font-size: $--size-font-x-large;
  &:after {
    content: '';
    position: absolute;
    border-bottom: 1px solid $--color-text-placeholder; //$--color-border-1level;
    bottom: 0;
    left: 0;
    right: 0;
  }
}
.form {
  background-color: #fff;
  padding: 15px;
  .comp {
    padding: 8px;
    margin-left: 0;
    margin-right: 0;
    :deep(.el-form-item) {
      margin-bottom: 0;
    }
  }
}
.footer {
  display: flex;
  justify-content: center;
  padding: 40px 15px 15px 15px;
  &::before {
    content: '';
    position: absolute;
    border-top: 1px solid $--color-text-placeholder;
    top: 15px;
    left: 0;
    right: 0;
  }
}
</style>
